using GEM.Application.Common;
using GEM.Application.Contracts;
using GEM.Application.Contracts.Jwt;
using GEM.Domain.Entities.App;
using GEM.Domain.Events;
using GEM.Domain.Repositories;
using Microsoft.Extensions.Logging;

namespace GEM.Application.Services;

public class AuthService
{
    private readonly IRepository<AppUser> _userRepo;
    private readonly IRepository<AppRole> _roleRepo;
    private readonly IJwtTokenService _IJwtTokenService;
    private readonly ILogger<AuthService> _logger;
    private readonly IDomainEventDispatcher _domainEventDispatcher;
    //依赖注入
    public AuthService(IDomainEventDispatcher domainEventDispatcher, ILogger<AuthService> logger, IRepository<AppUser> userRepo, IRepository<AppRole> roleRepo, IJwtTokenService IJwtTokenService)
    {
        _userRepo = userRepo;
        _roleRepo = roleRepo;
        _logger = logger;
        _domainEventDispatcher = domainEventDispatcher;
        _IJwtTokenService = IJwtTokenService;
    }

    //注册用户
    public async Task<dynamic> RegisterAsync(string username, string password)
    {
        //1. 检查用户名是否存在
        var exists = (await _userRepo.GetAllAsync()).Any(u => u.Username == username);
        if (exists)
        {
            return ApiResponse<string>.Fail(4001, "用户名已存在,请使用其他用户名!!");
        }

        //2. 生成盐和加密密码
        var salt = Guid.NewGuid().ToString("N");  //N表示无短横线(-)
        var hashedPwd = HashPassword(password, salt);

        var user = new AppUser { Username = username, Password = hashedPwd, Salt = salt };

        // 保存用户
        await _userRepo.CreateAsync(user);

        // 触发用户注册事件
        user.Register();

        // 分发领域事件(触发用户注册事件)
        await _domainEventDispatcher.DispatchAsync(user.DomainEvents);

        // 清除已处理的事件
        user.ClearDomainEvents();

        return ApiResponse<string>.Success("注册成功");

    }

    public async Task<dynamic> LoginAsync(string username, string password)
    {
        var user = await _userRepo.GetSingleWithIncludesAsync(
        u => u.Username == username,
        u => u.Roles
        );
        if (user == null)
        {
            return ApiResponse<string>.Fail(4001, "用户不存在，请确认后重试!!");
        }

        var hashedPwd = HashPassword(password, user.Salt);
        if (user.Password != hashedPwd)
        {
            return ApiResponse<string>.Fail(4002, "账号或密码错误!!"); ;
        }
        var token = _IJwtTokenService.GenerateToken(user.Id, user.Username, user.Roles.Select(r => r.RoleName));
        _logger.LogInformation("Nlog日志系统:调用登录方法");
        return ApiResponse<string>.Success(token, "登录成功");
    }

    // 对用户密码进行加密（哈希）
    private string HashPassword(string password, string salt)
    {
        // 简单示例，实际请用更安全的哈希算法
        using var sha256 = System.Security.Cryptography.SHA256.Create();
        var bytes = System.Text.Encoding.UTF8.GetBytes(password + salt);
        var hash = sha256.ComputeHash(bytes);
        return Convert.ToBase64String(hash);
    }

}